import json
import time
import requests


def unixtime() -> int:
    return int(time.time())


def unixday() -> int:
    t = unixtime()
    t += 28800  # 加8小时，调为北京时间
    t -= t % 86400  # 去零头，取0时
    t -= 28800  # 减8小时，调为伦敦时间
    return t


class Bili:
    def __init__(self):
        self.session = requests.session()
        self.headers = {
            'User-Agent':
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"
        }

    # HTTP请求 返回JSON
    def http_get(self, url):
        response = self.session.get(url, headers=self.headers)
        return response.json()

    # 视频API
    def call_api_view(self, aid: int):
        url = 'http://api.bilibili.com/medialist/gateway/base/resource/info?rid={0}&type=2'.format(
            aid)
        return self.http_get(url)

    # 频道API
    def call_api_channel(self, channel: int, offset: int = 0):
        url = 'https://api.bilibili.com/x/web-interface/web/channel/multiple/list?channel_id={0}&sort_type=new&page_size=30'.format(
            channel)
        if offset != 0:
            url += "&offset={0}".format(offset)
        return self.http_get(url)


# 递归调用频道API，直到曲目的投稿时间早于start_time为止
def get_recent_videos(channel: int, start_time: int, recorder: dict,
                      cache: dict):
    b = Bili()
    earlist_pubdate = unixtime()
    offset = 0
    cnt = 0
    while earlist_pubdate >= start_time:
        json_data = b.call_api_channel(channel, offset)
        data = json_data['data']
        list = data['list']
        offset = data['offset']
        # 对于列表中的数据，逐一调用视频API，查询各项数据
        for v in list:
            aid = v['id']
            # 如果缓存中有，就从缓存中提取
            if cache and aid in cache:
                cnt += 1
                print(cnt, '\t', cache[aid]['title'])
                recorder[aid] = cache[aid]
                continue
            video = dict()
            # 搬运5个属性到video里
            video['aid'] = v['id']
            video['title'] = v['name']
            for key in ['bvid', 'author_id', 'author_name']:
                video[key] = v[key]
            # 调用视频具体数据的API
            video_json = b.call_api_view(aid)
            if video_json['code'] != 0:
                print("【异常】code: {0}".format(video_data['code']))
                break
            video_data = video_json['data']
            video['pubdate'] = video_data['pubtime']
            if video['pubdate'] < start_time:
                earlist_pubdate = video['pubdate']
                break
            video['copyright'] = video_data['copyright']
            cnt_info = video_data['cnt_info']
            attris = {
                'view': 'play',
                'reply': 'reply',
                'coin': 'coin',
                'favorite': 'collect',
                'share': 'share',
                'danmaku': 'danmaku',
                'like': 'thumb_up'
            }
            for key, val in attris.items():
                video[key] = cnt_info[val]
            video['added'] = unixtime()
            cnt += 1
            print(cnt, '\t', video['title'])
            recorder[aid] = video
    return recorder


# 写入文件
def write_file(json_data, file_path):
    with open(file_path, 'w', encoding='utf8') as file_obj:
        json.dump(json_data, file_obj, ensure_ascii=False)


# main
lty_videos = dict()  #8564 这是洛天依的频道id 下同
yh_videos = dict()  #129641
yzl_videos = dict()  #201481
day = unixday()  #日期
length = 86400 * 14  #两周

print("\n\n开始获取洛天依数据")
get_recent_videos(8564, unixtime() - length, lty_videos, None)
write_file(list(lty_videos.values()), ".\datas\lty_{0}.json".format(day))
print("写出洛天依数据完毕")

print("\n\n开始获取言和数据")
get_recent_videos(129641, unixtime() - length, yh_videos, lty_videos)
write_file(list(yh_videos.values()), ".\datas\yh_{0}.json".format(day))
print("写出言和数据完毕")

print("\n\n开始获取乐正绫数据")
get_recent_videos(201481, unixtime() - length, yzl_videos, lty_videos)
write_file(list(yh_videos.values()), ".\datas\yzl_{0}.json".format(day))
print("写出乐正绫数据完毕")

print("\n\n运行完毕")